import { useRef } from 'react';
import type { Plugins, Timeout } from '../index.type';
import { subscribeReVisible } from '../utils/subscribeReVisible';

export const usePollingPlugin: Plugins<any, any[]> = (fetchInstance, options) => {
  const {
    pollingInterval, //发起下一次请求的间隔时间
    pollingWhenHidden = false, // true:文档隐藏时继续轮询,false时，文档不可见时停止轮询，文档可见时就要开启轮询
    pollingErrorRetryCount = -1, //轮询错误重试次数。如果设置为 -1，则无限次
  } = options;

  const timerRef = useRef<Timeout>();
  const unsubscribeRef = useRef<() => void>();
  const countRef = useRef<number>(0);

  const stopPolling = () => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }
    unsubscribeRef.current?.();
  };

  if (!pollingInterval) {
    stopPolling();
    return {};
  }

  return {
    onBefore: () => {
      if (pollingErrorRetryCount !== -1 && countRef.current > pollingErrorRetryCount) {
        // 重试完成，再次run时从头开始重试
        countRef.current = 0;
      }
      stopPolling();
    },
    onSuccess: () => {
      countRef.current = 0;
    },
    onError: () => {
      countRef.current += 1;
    },
    onFinally: () => {
      if (pollingErrorRetryCount === -1 || (pollingErrorRetryCount !== -1 && countRef.current <= pollingErrorRetryCount)) {
        timerRef.current = setTimeout(() => {
          //文档不可见时停止轮询 && 文档不可见
          if (!pollingWhenHidden && document.visibilityState === 'hidden') {
            unsubscribeRef.current = subscribeReVisible(() => {
              //文档可见时才执行回调函数（重新请求数据）--走到onFinally--又重新setTimeout();
              fetchInstance.refresh();
            });
          } else {
            fetchInstance.refresh();
          }
        }, pollingInterval);
      } else {
        countRef.current = 0;
      }
    },
    onCancel: () => {
      stopPolling();
    },
  };
};